package xyz.zchao.blog.controller;

import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import xyz.zchao.blog.annotation.IgnoreToken;
import xyz.zchao.blog.exception.CustomizeException;
import xyz.zchao.blog.pojo.User;
import xyz.zchao.blog.pojo.User;
import xyz.zchao.blog.service.UserService;
import xyz.zchao.blog.util.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Controller
@RequestMapping("/user")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Resource
    private UserService userService;

    /**
     * 用户注册处理
     *
     * @param registerUser
     * @return
     */
    @IgnoreToken
    @PostMapping("/register")
    @ResponseBody
    public ResultVO<?> userRegister(@RequestBody @Valid User registerUser) throws Exception {
        registerUser.setAvatar("/img/default_avatar.png");
        try {
            userService.findUserByUserName(registerUser.getUserName());
        } catch (CustomizeException e) {
            //抛出自定义异常，说明用户不存在，执行注册
            userService.create(registerUser);
            log.info("注册成功");
            return new ResultVO<String>(ResultCode.SUCCESS, "注册成功!");
        }
        log.info("注册失败");
        return new ResultVO<String>(ResultCode.FAILED, "用户已存在!");
    }

    /**
     * 用户登录处理
     *
     * @param loginUser
     * @return
     * @throws Exception
     */
    @IgnoreToken
    @PostMapping("/login")
    @ResponseBody
    public ResultVO userLogin(@RequestBody @Valid User loginUser,HttpServletResponse response) throws Exception {
        User user = userService.findUserByUserName(loginUser.getUserName());
        if (loginUser.getUserPassword().equals(EncryptionUtil.decrypted(user.getUserPassword()))) {
            //要添加到token的数据
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", user.getUserId());
            claims.put("roleId", user.getRoleId());
            //生成访问的token
            String access_token = JwtTokenUtil.createToken(claims);
            //设置cookie
            Cookie cookie1 = new Cookie("access_token", access_token);
            Cookie cookie2 = new Cookie("uid", String.valueOf(user.getUserId()));
            cookie1.setPath("/");
            cookie1.setMaxAge(60*60);
//            cookie1.setSecure(true);
//            cookie1.setHttpOnly(true);
            cookie2.setPath("/");
            cookie2.setMaxAge(60*60);
            response.addCookie(cookie1);
            response.addCookie(cookie2);
            //响应的数据
            Map<String, Object> data=new HashMap<>();
            data.put("access_token", access_token);
            data.put("userId",user.getUserId());
            log.info("登录成功");
            return new ResultVO<>(ResultCode.SUCCESS,data);
        } else {
            log.info("密码错误");
            return new ResultVO<>(ResultCode.FAILED, "密码错误！");
        }
    }

    /**
     * 个人中心页面
     *
     * @param uid
     * @param model
     * @return
     * @throws Exception
     */
    @IgnoreToken
    @GetMapping("/center/{uid}")
    public String userCenter(@PathVariable("uid") Integer uid, Model model) throws Exception {
        User user = userService.retrieveById(uid);
        user.setUserPassword(EncryptionUtil.decrypted(user.getUserPassword()));
        model.addAttribute("user", user);
        return "userinfo";
    }

    /**
     * 获取已登录用户信息(原则上应该从缓存中拿，缓存没有再从数据库拿，这里暂时从数据库拿)
     *
     * @param request
     * @return
     */
    @GetMapping("/getLoggedInUserInfo")
    @ResponseBody
    public ResultVO getUserInfo(HttpServletRequest request) {
        //接收从拦截器传来验证成功的token中的userId
        Integer userId = (Integer) request.getAttribute("userId");
        if (userId == null) {
            throw new CustomizeException(ResultCode.USER_NOT_LOGGED_IN);
        }
        User user = userService.retrieveById(userId);
        //封装部分数据
        Map<String, Object> data = new HashMap<>();
        data.put("userId", user.getUserId());
        data.put("userName", user.getUserName());
        data.put("avatar", user.getAvatar());
        data.put("roleId", user.getRoleId());
        return new ResultVO<>((ResultCode.SUCCESS), data);
    }

    /**
     * 用户信息更新(原则上更新数据库并更新缓存)
     *
     * @param uid
     * @param record
     * @param request
     * @return
     */
    @PutMapping("/{uid}")
    @ResponseBody
    public ResultVO updateUser(@PathVariable("uid") Integer uid, @RequestBody User record, HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("userId");
        if (userId != uid) {
            throw new CustomizeException(ResultCode.USER_INCONSISTENT);
        }
        record.setUserId(uid);
        record.setUserPassword(null);
        userService.update(record);
        return new ResultVO(ResultCode.SUCCESS, "/user/center/" + record.getUserId());

    }

    /**
     * 退出登录处理
     *
     * @return
     */
/*    @GetMapping("/logout")
    public String logout(HttpServletResponse response) {
        Cookie cookie = new Cookie("access_token", null);
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        return "redirect:/login";
    }*/
}
